#include "sgu.h"

SGU_NS_BEGIN


//**** Memory

Memory::Memory()
{
	_size = 0;
	_allocsize = _s_minsize;
	_ptr = malloc(_allocsize);
}

Memory::Memory(size_t z)
{
	_size = z;
	_allocsize = z >? _s_minsize;
	_ptr = malloc(_allocsize);
}

Memory::~Memory()
{
	free(_ptr);
}

Memory::Memory(const ConstSegment & a)
{
	_size = a.size();
	_allocsize = _size >? _s_minsize;
	_ptr = malloc(_allocsize);
	memcpy(_ptr,a.cptr(),_size);
}


Memory & Memory::operator = (const ConstSegment & a)
{
	ASSERT(this!=&a);
	free(_ptr);
	_size = a.size();
	_allocsize = _size >? _s_minsize;
	_ptr = malloc(_allocsize);
	memcpy(_ptr,a.cptr(),_size);
	return *this;
}

size_t Memory::size() const
{
	return _size;
}

const char * Memory::cptr() const
{
	return (const char*)_ptr;
}

char * Memory::ptr() const
{
	return (char *)_ptr;
}

void Memory::resize(size_t n)
{
	if(n==size()) return;
	if(n > _allocsize)
	{
		_allocsize = n+n/2;
		_ptr = realloc(_ptr, _allocsize);
	}
	else
	{
		if(n<_allocsize/2 && _allocsize>_s_minsize)
		{
			_allocsize = n+n/2 >? _s_minsize;
			_ptr = realloc(_ptr, _allocsize);
		}
	};
	_size = n;
}

void Memory::clear(size_t n)
{
	if(n==size()) return;
	if(n > _allocsize)
	{
		free(_ptr);
		_allocsize = n+n/2;
		_ptr = malloc(_allocsize);
	}
	else
	{
		if(n<_allocsize/2 && _allocsize>_s_minsize)
		{
			free(_ptr);
			_allocsize = n+n/2 >? _s_minsize;
			_ptr = malloc(_allocsize);
		}
	};
	_size = n;
}


void Memory::clear()
{
	if(size())
	{
	 	free(_ptr);
		_allocsize = _s_minsize;
		_ptr = malloc(_allocsize);
		_size = 0;
	};
}

void Memory::serialize(BOStorage &) const {TODO;}
void Memory::serialize(BIStorage &) {TODO;}
void Memory::serialize(TOStorage &) const {TODO;}
void Memory::serialize(TIStorage &) {TODO;}



#if 0
void Memory::Serialize(BOStream & s) const
{
	s << Size();
	s.Write(ConstPtr(),Size());
}

void Memory::Serialize(BIStream & s)
{
	size_t sz;
	s >> sz;
	ClearReSize(sz);
	s.Read(Ptr(),sz);
}

void Memory::Serialize(TOStream & s) const
{
	s << _T("Memory[") << Size() << _T("]") << TOStream::e_BeginBlock;
	s.PushRadix(TOStream::e_Hex);
	size_t n;
	LOOP(n,Size())
	{
		s << (DWORD)ConstPtr()[n];
		if((n%16 == 15) && (n+1<Size())) s << TOStream::e_EOL;
	};
	s.PopRadix();
	s << TOStream::e_EndBlock;
}

void Memory::Serialize(TIStream & s)
{
	size_t n;
	s >> _T("Memory [") >> n >> _T("]") >> TIStream::e_BeginBlock;
	ClearReSize(n);
	LOOP(n,Size())
	{
		DWORD k;
		s >> k;
		ASSERT(INCC(k,0,UCHAR_MAX));
		Ptr()[n] = (BYTE)k;
	};
	s >> TIStream::e_EndBlock;
}

#endif




SGU_NS_END
